﻿using System;
using System.Linq;
using CardPlay.Model.CardModel;
using CardPlay.Model.GameModel;
using CardPlay.Model.GameModel.Actions;
using CardPlay.Model.GameModel.Presentation;
using CardPlay.Model.Layout;

namespace CardPlay.DemoPack.Games.FreeCellVariants
{
    [Game("AD88A311-5C3C-4EF1-820D-E76DAF9D2A61", LevelOfDifficulty.Medium, LevelOfSkill.MostlySkill, DurationOfPlay.Within5To10Minutes, Family = FamilyName)]
    public class Penguin : FreeCellBase
    {
        public Penguin()
        {
            TotalTableaus = 7;
            TotalReserves = 7;
        }

        public override ILayoutSite CreatePresentation(IPresentationContext presentation)
        {
            var metrics = presentation.Metrics;

            var root = new GridLayout
            {
                Columns = 3,
                Rows = 1,
                HorizontalContentAlignment = HorizontalAlignment.Center,
                VerticalContentAlignment = VerticalAlignment.Stretch
            };

            {
                var leftArea = new SideBySideLayout
                {
                    HorizontalContentAlignment = HorizontalAlignment.Stretch,
                    Direction = SpreadDirection.Vertical,
                    MinimumSpacing = metrics.MinSpacingDown,
                    MaximumSpacing = metrics.MinSpacingDown
                };

                {
                    var reserve = presentation.CreateRowLayout(); // CreateSideBySideLayout(metrics);
                    var style  = new VisualTraits
                    {
                        EmptyCue = () => EmptyPileCue.CardSite,
                        Arrangement = CardArrangement.StackSquare,
                        ContentFit = ContentFit.FitHeight
                    };

                    foreach (var pile in PilesNamed(AnyReserve))
                        reserve.Add(presentation.CreatePileVisual(pile.Name, style));

                    leftArea.Add(reserve);
                }

                {
                    var tableau = presentation.CreateRowLayout(); // CreateSideBySideLayout(metrics);
                    tableau.VerticalContentAlignment = VerticalAlignment.Top;

                    foreach (var pile in PilesNamed(AnyTableau))
                        tableau.Add(presentation.CreatePileVisual(pile.Name, StandardStyles.Tableau));

                    leftArea.Add(tableau);
                }

                root.Add(leftArea);
            }

            {
                root.Add(presentation.CreateMimimalSpacer());
            }

            {
                var foundations = presentation.CreateColumnLayout(); // CreateSideBySideLayout(metrics);
                //foundations.Direction = SpreadDirection.Vertical;

                foreach (var name in PilesNamed(AnyFoundation).Select(pile => pile.Name))
                    foundations.Add(presentation.CreatePileVisual(name, StandardStyles.Foundation));

                root.Add(foundations);
            }

            return root;
        }

        protected override void PrepareDealScript(DealScript script)
        {
        }

        protected override IDealAction CreateDealScript()
        {
            var selector = new Predicate<CardFace>(face => face.Rank == FoundationBaseRank);
            var sequence = new DealSequence();

            sequence.Add(new DealCardAction(Foundation1) { Orientation = CardOrientation.FaceUp });
            sequence.Add(new DealCardAction(Foundation2, selector) { Orientation = CardOrientation.FaceUp });
            sequence.Add(new DealCardAction(Foundation3, selector) { Orientation = CardOrientation.FaceUp });
            sequence.Add(new DealCardAction(Tableau1, selector) { Orientation = CardOrientation.FaceUp });

            var script = new DealScript();

            script.Deal("6 up").To(Tableau1);
            script.Deal("7 up").To(Tableau2);
            script.Deal("7 up").To(Tableau3);
            script.Deal("7 up").To(Tableau4);
            script.Deal("7 up").To(Tableau5);
            script.Deal("7 up").To(Tableau6);
            script.Deal("7 up").To(Tableau7);

            sequence.Add(script.Compile());

            return sequence;
        }

        protected override bool IsTableauMovePossible(RemovePileAction action)
        {
            return true;
        }
    }
}
